#include <errno.h>
#include <libudev.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// gcc -o get_devlist_udev get_devlist_udev.c -ludev

void print_device_info(struct udev_device *dev) {
  const char *action = udev_device_get_action(dev);
  if (action) {
    printf("动作: %s\n", action);
  }
#if 0
  printf("设备节点: %s ", udev_device_get_devnode(dev));
  printf("子系统: %s\n", udev_device_get_subsystem(dev));
  printf("设备类型: %s", udev_device_get_devtype(dev));
  printf("系统路径: %s\n", udev_device_get_syspath(dev));
#endif
  // 获取总线号和设备号
  const char *busnum = udev_device_get_sysattr_value(dev, "busnum");
  const char *devnum = udev_device_get_sysattr_value(dev, "devnum");
  if (busnum && devnum) {
    printf("总线号: %s, 设备号: %s, ", busnum, devnum);
  }

  // 获取厂商和产品ID
  const char *idVendor = udev_device_get_sysattr_value(dev, "idVendor");
  const char *idProduct = udev_device_get_sysattr_value(dev, "idProduct");
  if (idVendor && idProduct) {
    printf("厂商ID: %s, 产品ID: %s\n", idVendor, idProduct);
  }
#if 1
  // 获取版本信息
  const char *bcdDevice = udev_device_get_sysattr_value(dev, "bcdDevice");
  if (bcdDevice) {
    printf("设备版本: %s\n", bcdDevice);
  }
#endif
  const char *vendor_db_str =
      udev_device_get_property_value(dev, "ID_VENDOR_FROM_DATABASE");
  if (vendor_db_str) {
    printf("设备厂商数据库名称: %s", vendor_db_str);
  } else {
    printf("未找到 设备厂商数据库名 \n");
  }
  // ID_MODEL_FROM_DATABASE
  const char *id_db_str =
      udev_device_get_property_value(dev, "ID_MODEL_FROM_DATABASE");
  if (id_db_str) {
    printf(" %s\n", id_db_str);
  } else {
    printf("\n");
  }
#if 0
  // 获取设备类、子类和协议
  const char *bDeviceClass = udev_device_get_sysattr_value(dev, "bDeviceClass");
  const char *bDeviceSubClass =
      udev_device_get_sysattr_value(dev, "bDeviceSubClass");
  const char *bDeviceProtocol =
      udev_device_get_sysattr_value(dev, "bDeviceProtocol");
  if (bDeviceClass) {
    printf("设备类: %s, 子类: %s, 协议: %s\n", bDeviceClass,
           bDeviceSubClass ? bDeviceSubClass : "N/A",
           bDeviceProtocol ? bDeviceProtocol : "N/A");
  }
#endif
  // 获取制造商和产品字符串
  const char *manufacturer = udev_device_get_sysattr_value(dev, "manufacturer");
  const char *product = udev_device_get_sysattr_value(dev, "product");
  if (manufacturer) {
    printf("制造商: %s ", manufacturer);
  }
  if (product) {
    printf("产品: %s\n", product);
  }
#if 0
    // 获取序列号
    const char *serial = udev_device_get_sysattr_value(dev, "serial");
    if (serial) {
        printf("序列号: %s\n", serial);
    }
    
    // 获取速度信息
    const char *speed = udev_device_get_sysattr_value(dev, "speed");
    if (speed) {
        printf("速度: %s\n", speed);
    }
#endif
#if 0
  // 打印所有设备属性
  printf("属性:\n");
  struct udev_list_entry *properties =
      udev_device_get_properties_list_entry(dev);
  struct udev_list_entry *entry;
  udev_list_entry_foreach(entry, properties) {
    const char *name = udev_list_entry_get_name(entry);
    const char *value = udev_list_entry_get_value(entry);
    printf("  %s=%s\n", name, value);
  }
#endif
  printf("\n\n");
}

int enumerate_usb_devices(struct udev *udev_ctx) {
  struct udev_enumerate *enumerate;
  struct udev_list_entry *devices, *entry;
  struct udev_device *dev;
  int count = 0;

  // 创建枚举对象
  enumerate = udev_enumerate_new(udev_ctx);
  if (!enumerate) {
    fprintf(stderr, "无法创建枚举对象\n");
    return -1;
  }

  // 添加匹配条件 - 只关注USB设备
  udev_enumerate_add_match_subsystem(enumerate, "usb");
  udev_enumerate_add_match_property(enumerate, "DEVTYPE", "usb_device");

  // 执行枚举
  if (udev_enumerate_scan_devices(enumerate) < 0) {
    fprintf(stderr, "设备枚举失败\n");
    udev_enumerate_unref(enumerate);
    return -1;
  }

  // 获取设备列表
  devices = udev_enumerate_get_list_entry(enumerate);
  if (!devices) {
    printf("未找到USB设备\n");
    udev_enumerate_unref(enumerate);
    return 0;
  }

  // 遍历设备列表
  udev_list_entry_foreach(entry, devices) {
    const char *syspath = udev_list_entry_get_name(entry);

    // 从系统路径创建设备对象
    dev = udev_device_new_from_syspath(udev_ctx, syspath);
    if (dev) {
      printf("=== USB设备 %d ===\n", ++count);
      print_device_info(dev);
      udev_device_unref(dev);
    }
  }

  // 释放枚举对象
  udev_enumerate_unref(enumerate);

  return count;
}

int main() {
  struct udev *udev_ctx;
  int device_count;

  // 创建udev上下文
  udev_ctx = udev_new();
  if (!udev_ctx) {
    fprintf(stderr, "无法创建udev上下文\n");
    return EXIT_FAILURE;
  }

  printf("开始枚举系统中的USB设备...\n\n");

  // 枚举USB设备
  device_count = enumerate_usb_devices(udev_ctx);

  if (device_count < 0) {
    fprintf(stderr, "枚举过程中发生错误\n");
  } else {
    printf("共找到 %d 个USB设备\n", device_count);
  }

  // 释放udev上下文
  udev_unref(udev_ctx);

  return EXIT_SUCCESS;
}